import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart' as my_get;
import 'package:image_picker/image_picker.dart';
import 'package:o2oa_all_platform/common/extension/index.dart';
import 'package:uuid/uuid.dart';

import '../../../../common/api/index.dart';
import '../../../../common/models/index.dart';
import '../../../../common/utils/index.dart';
import '../../../../common/values/index.dart';
import '../../../../common/widgets/index.dart';
// [baidumap8]
// import '../../../common/baidu_map/index.dart';
import '../../contact/person/index.dart';
import '../chat_message_tool.dart';
import '../conversation_picker/view.dart';
import '../group_members/index.dart';
import 'index.dart';

class ImChatController extends my_get.GetxController {
  ImChatController();

  final state = ImChatState();
  final messageTool =  ImChatMessageTool();
  IMConversationInfo? conversationInfo;
  String? _conversationId;
  int page = 1; //当前页面
  int totalPage = 1; //总页数
  var _isLoading = false; //
  Map<String, String> headers = {};

  // 聊天输入框的控制器
  final TextEditingController chatInputController = TextEditingController();
  final ScrollController chatInputScrollController = ScrollController();
  final FocusNode chatInputNode = FocusNode();
  // 修改群名输入框控制器
  final TextEditingController updateGroupTitleInputController =
      TextEditingController();
  // 聊天列表滚动控制器
  final ScrollController msgListScrollController = ScrollController();


  final Uuid _uuid = const Uuid();
  // 拍照 图片选择
  final ImagePicker _imagePicker = ImagePicker();

  // 消息
  final eventBus = EventBus();
  final eventId = 'IMChat';

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    messageTool.init();

    super.onInit();
  }

  

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    // 各个监听
    _initListener();
    _loadEmojiTextList();
    // 初始化数据
    headers[O2ApiManager.instance.tokenName] =
        O2ApiManager.instance.o2User?.token ?? '';
    var map = my_get.Get.arguments;
    if (map != null) {
      state.title = map["title"] ?? "";
      OLogger.d("聊天标题 title: ${state.title} ");
      String id = map["conversationId"] ?? "";
      OLogger.d("会话id: $id ");
      if (id.isNotEmpty) {
        _conversationId = id;
        loadConversationInfo();
        loadChatMessageList();
        readConversation();
      } else {
        Loading.showError('args_error'.tr);
      }
    } else {
      Loading.showError('args_error'.tr);
    }
    super.onReady();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    eventBus.off(EventBus.websocketCreateImMsg, eventId);
    eventBus.off(EventBus.websocketRevokeImMsg, eventId);
    eventBus.off(EventBus.websocketImConversationUpdateMsg, eventId);
    eventBus.off(EventBus.websocketImConversationDeleteMsg, eventId);
    messageTool.dispose();
    super.onClose();
  }

  _initListener() {
    //监听websocket聊天消息
    eventBus.on(EventBus.websocketCreateImMsg, eventId, (arg) {
      OLogger.d("收到websocket im 新消息！");
      if (arg is IMMessage) {
        IMMessage message = arg;
        if (message.conversationId != null &&
            message.conversationId == _conversationId) {
          // 判断不存在 就添加
          if (!state.msgList.any((element) => element.id == message.id)) {
            OLogger.d("当前会话的消息，新增一条");
            _addMessageToUI(message);
            // 滚动底部
           _delayScorllToBottom();
          }
        }
      }
    });
    // 监听撤回消息
    eventBus.on(EventBus.websocketRevokeImMsg, eventId, (arg) {
      OLogger.d("收到websocket im 撤回消息！");
      if (arg is IMMessage) {
        IMMessage message = arg;
        if (message.conversationId != null &&
            message.conversationId == _conversationId) {
          state.msgList.remove(message);
        }
      }
    });
    // 更新会话
    eventBus.on(EventBus.websocketImConversationUpdateMsg, eventId, (arg) {
      if (arg is IMConversationInfo && arg.id == _conversationId) {
        final personList = arg.personList ?? [];
        if (!personList
            .contains(O2ApiManager.instance.o2User?.distinguishedName)) {
          my_get.Get.back();
          Loading.showError('im_chat_error_conversation_delete'.tr);
        } else {
          loadConversationInfo();
        }
      }
    });
    // 删除会话
    eventBus.on(EventBus.websocketImConversationDeleteMsg, eventId, (arg) {
      if (arg is IMConversationInfo && arg.id == _conversationId) {
        my_get.Get.back();
        Loading.showError('im_chat_error_conversation_delete'.tr);
      }
    });
    msgListScrollController.addListener(scrollListener);
    // 监听输入法变化
    chatInputNode.addListener(() {
      if (chatInputNode.hasFocus) {
        state.toolBoxType = 0; // 关闭其他工具栏
        // 这里输入法出现的动画时间比较长，延迟滚动。。。。。
        Future.delayed(const Duration(milliseconds: 500), () {
          msgListScrollController.animateTo(0.0,
              duration: const Duration(milliseconds: 200),
              curve: Curves.easeInOut);
        });
      }
    });
  }

 

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
  }

  void scrollListener() {
    if (msgListScrollController.position.pixels >=
        msgListScrollController.position.maxScrollExtent) {
      if (_isLoading) return;
      if (!state.hasMore) return;
      _isLoading = true;
      loadNextPageChatMessageList();
    }
  }

  /// 加载表情包
  Future<void> _loadEmojiTextList() async {
    state.emojiTextList.clear();
    EmojiJsonData? emojiJsonData = await O2Emoji.instance.getEmojiJsonData();
    if (emojiJsonData != null) {
      switch (state.emojiType.value) {
        case EmojiType.smileOrPerson:
          state.emojiTextList.addAll(emojiJsonData.smileOrPerson ?? []);
          break;
        case EmojiType.animals:
          state.emojiTextList.addAll(emojiJsonData.animals ?? []);
          break;
        case EmojiType.food:
          state.emojiTextList.addAll(emojiJsonData.food ?? []);
          break;
        case EmojiType.activities:
          state.emojiTextList.addAll(emojiJsonData.activities ?? []);
          break;
        case EmojiType.travel:
          state.emojiTextList.addAll(emojiJsonData.travel ?? []);
          break;
        case EmojiType.symbol:
          state.emojiTextList.addAll(emojiJsonData.symbol ?? []);
          break;
        case EmojiType.objects:
          state.emojiTextList.addAll(emojiJsonData.objects ?? []);
          break;
      }
    }
  }

  ///  消息列表 第一页 需要滚动到底部
  Future<void> loadChatMessageList() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      _isLoading = false;
      return;
    }
    page = 1;
    var msgPage = await MessageCommunicationService.to
        .conversationMessageByPage(_conversationId!, page);
    if (msgPage != null) {
      totalPage = msgPage.totalPage;
      state.hasMore = totalPage > page;
      state.msgList.clear();
      state.msgList.addAll(msgPage.list);
      _delayScorllToBottom();
    }
    _isLoading = false;
    // 滚动到底部
  }

  /// 加载更多数据 给下拉刷新用
  /// 下拉不是刷新 是加载更多 这里跟普通的列表不一样
  /// 获取下一页历史消息 不滚动
  Future<void> loadNextPageChatMessageList() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      _isLoading = false;
      return;
    }
    if (totalPage < page + 1) {
      OLogger.e('没有更多数据了， totalPage: $totalPage');
      _isLoading = false;
      return;
    }
    page = page + 1;
    OLogger.d("加载更多聊天消息！ page:$page");
    var msgPage = await MessageCommunicationService.to
        .conversationMessageByPage(_conversationId!, page);
    if (msgPage != null) {
      totalPage = msgPage.totalPage;
      state.hasMore = totalPage > page;
      state.msgList.addAll(msgPage.list);
    }
    _isLoading = false;
  }

  /// 获取配置文件
  Future<void> loadImConfig() async {
    state.imConfig.value = await MessageCommunicationService.to.getImConfig();
    OLogger.d("getImConfig: ${state.imConfig.value?.toJson()} ");
    if (state.imConfig.value?.enableClearMsg == true &&
        ((conversationInfo?.type == O2.imConversationTypeGroup &&
                conversationInfo?.adminPerson ==
                    O2ApiManager.instance.o2User?.distinguishedName) ||
            (conversationInfo?.type == O2.imConversationTypeSingle))) {
      if (!state.menuList
          .any((menu) => menu.type == IMChatMenuType.deleteConv)) {
        state.menuList.add(IMChatMenu(
            'im_chat_action_menu_delete_conversation'.tr,
            IMChatMenuType.deleteConv));
      }
    }
    OLogger.d("菜单列表： ${state.menuList.map((e) => e.toJson()).toList()}");
  }
 

  ///
  /// 获取会话对象
  ///
  Future<void> loadConversationInfo() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      return;
    }
    var conversation =
        await MessageCommunicationService.to.getConversation(_conversationId!);
    if (conversation != null) {
      conversationInfo = conversation;
      loadImConfig();
      // 设置标题 工具栏等
      _updateTitle();
      // 顶部菜单
      if (conversationInfo?.type == O2.imConversationTypeGroup) {
        // 防止重复添加菜单按钮
        if (!state.menuList.any((menu) =>
            menu.type == IMChatMenuType.updateTitle ||
            menu.type == IMChatMenuType.updateMembers ||
            menu.type == IMChatMenuType.showGroupInfo)) {
          state.menuList.add(IMChatMenu(
              'im_chat_action_menu_show_group_info'.tr,
              IMChatMenuType.showGroupInfo));
          if (conversationInfo?.adminPerson ==
              O2ApiManager.instance.o2User?.distinguishedName) {
            state.menuList.add(IMChatMenu(
                'im_chat_action_menu_update_group_title'.tr,
                IMChatMenuType.updateTitle));
            state.menuList.add(IMChatMenu(
                'im_chat_action_menu_update_group_members'.tr,
                IMChatMenuType.updateMembers));
          }
        }
      }
    }
  }

  ///
  /// 消息 已读
  ///
  Future<void> readConversation() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      return;
    }
    final result =
        await MessageCommunicationService.to.readConversation(_conversationId!);
    OLogger.d("阅读会话： ${result?.toJson()}");
  }

  ///
  /// 更新群名称
  ///
  Future<void> updateGroupTitle(String title) async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      return;
    }
    if (conversationInfo != null &&
        conversationInfo?.type == O2.imConversationTypeGroup) {
      var form = IMConversationInfo();
      form.id = _conversationId;
      form.title = title;
      final result =
          await MessageCommunicationService.to.updateConversation(form);
      OLogger.d("更新会话title： $result");
      if (result != null) {
        conversationInfo?.title = title;
        _updateTitle();
        Loading.toast('im_chat_success_update_group_title'.tr);
      }
    }
  }


  void _updateTitle() {
    //标题处理
    var title = '';
    if (conversationInfo != null) {
      // 单聊
      if (conversationInfo?.type == O2.imConversationTypeSingle) {
        var otherParty = conversationInfo?.personList?.firstWhereOrNull(
            (element) =>
                element != O2ApiManager.instance.o2User?.distinguishedName);
        if (otherParty != null && otherParty.isNotEmpty) {
          if (otherParty.contains("@")) {
            title = otherParty.substring(0, otherParty.indexOf("@"));
          } else {
            title = otherParty;
          }
        }
      } else {
        title = conversationInfo?.title ?? '';
      }
    }
    state.title = title;
  }

  /// 针对UI动画
  void _delayScorllToBottom() {
    // 滚动底部 这里需要等待刷新页面后才能滚动
    Future.delayed(const Duration(milliseconds: 200), () {
      msgListScrollController.animateTo(0.0,
          duration: const Duration(milliseconds: 200), curve: Curves.easeInOut);
    });
  }


  /// 关闭输入法
  void closeSoftInputAndOtherTools() {
    chatInputNode.unfocus(); // 关闭输入法
    state.toolBoxType = 0;
  }

  void clickVoiceBtn() {
    chatInputNode.unfocus(); // 关闭输入法
    if (state.toolBoxType == 1) {
      state.toolBoxType = 0;
    } else {
      state.toolBoxType = 1;
      _delayScorllToBottom();
    }
  }

  void clickShowKeyboardBtn() {
    state.toolBoxType = 0;
    chatInputNode.requestFocus();
  }

  void clickEmojiBtn() {
    chatInputNode.unfocus(); // 关闭输入法
    if (state.toolBoxType == 2) {
      state.toolBoxType = 0;
    } else {
      state.toolBoxType = 2;
      _delayScorllToBottom();
    }
  }

  void clickEmojiTypeBtn(EmojiType type) {
    state.emojiType.value = type;
    _loadEmojiTextList();
  }

  void clickMoreBtn() {
    chatInputNode.unfocus(); // 关闭输入法
    if (state.toolBoxType == 3) {
      state.toolBoxType = 0;
    } else {
      state.toolBoxType = 3;
      _delayScorllToBottom();
    }
  }

  void clickChoosePhotosBtn() {
    _pickImageByType(0);
  }

  void clickTakePhotoBtn() {
    _pickImageByType(1);
  }

  void clickChooseFileBtn() {
    _chooseFile();
  }

  void clickChooseLocationBtn() async {
    OLogger.d("选择位置");
    LocationData locationData =
        LocationData(LocationData.locationDataModePicker);
    var location = null; // [baidumap9]
    // var location = await BaiduMapPage.open(locationData);
    if (location != null && location is LocationData) {
      OLogger.d(
          '选择了。。。。${location.latitude} ${location.longitude} ${location.address} ');
      var msg = _createMsg(_locationMsgBody(location));
      if (msg != null) {
        _addMessageToUI(msg);
        _sendMessageToServer(msg);
      }
    }
  }

  /// 点击头像
  void clickAvatarToPerson(String person) {
    PersonPage.open(person);
  }

  ///
  /// 点击右上角菜单
  ///
  void clickActionMenu(IMChatMenu menu) {
    OLogger.d('点击了菜单，${menu.name}');
    // 先关闭右上角菜单，再继续执行 防止pop冲突
    Future.delayed(const Duration(seconds: 0), () {
      switch (menu.type) {
        case IMChatMenuType.report:
          _openReportDialog();
          break;
        case IMChatMenuType.showGroupInfo:
          _showGroupInfo();
          break;
        case IMChatMenuType.updateTitle:
          _openUpdateTitleDialog();
          break;
        case IMChatMenuType.updateMembers:
          openGroupMembers();
          break;
        case IMChatMenuType.deleteConv:
          _deleteConversation();
          break;
      }
    });
  }

  /// 删除会话
  void _deleteConversation() {
    var context = my_get.Get.context;
    if (context == null) {
      return;
    }
    if (conversationInfo != null) {
      if (conversationInfo?.type == O2.imConversationTypeSingle) {
        // 单聊
        O2UI.showConfirm(
            context, 'im_chat_confirm_delete_single_conversation'.tr,
            okPressed: () => _deleteSingleConv());
      } else {
        // 群聊
        O2UI.showConfirm(
            context, 'im_chat_confirm_delete_group_conversation'.tr,
            okPressed: () => _deleteGroupConv());
      }
    }
  }

  void _deleteSingleConv() async {
    final result = await MessageCommunicationService.to
        .deleteSingleConversation(_conversationId!);
    if (result != null) {
      my_get.Get.back();
    }
  }

  void _deleteGroupConv() async {
    final result = await MessageCommunicationService.to
        .deleteGroupConversation(_conversationId!);
    if (result != null) {
      my_get.Get.back();
    }
  }


  /// 显示群信息
  void _showGroupInfo() {
    if (conversationInfo != null) {
      GroupMembersPage.showGroupInfo(conversationInfo!);
    }
  }

  /// 更新群成员
  void openGroupMembers() async {
    if (conversationInfo != null) {
      await GroupMembersPage.updateMember(conversationInfo!);
      loadConversationInfo();
    }
  }

  /// 更新群名
  void _openUpdateTitleDialog() async {
    var context = my_get.Get.context;
    if (context == null) {
      return;
    }
    updateGroupTitleInputController.text = conversationInfo?.title ?? '';
    var result = await O2UI.showCustomDialog(
        my_get.Get.context,
        'im_chat_action_menu_update_group_title'.tr,
        TextField(
          controller: updateGroupTitleInputController,
          maxLines: 1,
          style: Theme.of(context).textTheme.bodyMedium,
          keyboardType: TextInputType.text,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            labelText: 'im_chat_action_menu_update_group_title_hint'.tr,
          ),
        ));
    OLogger.d('修改群名dialog，返回结果$result');
    if (result != null && result == O2DialogAction.positive) {
      var title = updateGroupTitleInputController.text;
      if (title.isEmpty) {
        Loading.toast('im_chat_error_update_group_title_not_empty'.tr);
      } else {
        updateGroupTitle(title);
      }
    }
  }

  /// 举报
  void _openReportDialog() async {
    var result = await O2UI.showCustomDialog(my_get.Get.context,
        'im_chat_action_menu_report'.tr, _reportFormWidget());
    OLogger.i('举报成功，返回结果$result');
  }

  Widget _reportFormWidget() {
    var context = my_get.Get.context;
    if (context == null) {
      return Container();
    }
    return Column(
      children: [
        TextField(
          maxLines: 1,
          style: Theme.of(context).textTheme.bodyMedium,
          keyboardType: TextInputType.text,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            labelText: 'im_chat_action_menu_report_form_reason'.tr,
          ),
        ),
        const SizedBox(
          height: 16,
        ),
        TextField(
          keyboardType: TextInputType.multiline,
          maxLines: 4,
          style: Theme.of(context).textTheme.bodyMedium,
          textInputAction: TextInputAction.done,
          decoration: InputDecoration(
            labelText: 'im_chat_action_menu_report_form_desc'.tr,
          ),
        ),
      ],
    );
  }

  ///
  /// 撤回消息
  ///
  void revokeMsg(IMMessage info) async {
    var back = await MessageCommunicationService.to.revokeMessage(info.id!);
    if (back != null) {
      state.msgList.remove(info);
      Loading.toast('im_chat_success_revoke'.tr);
    } else {
      Loading.showError('im_chat_error_revoke'.tr);
    }
  }

  ///
  /// 复制消息
  ///
  void copyTextMsg(IMMessage info) {
    if (info.toBody()?.type == IMMessageType.text.name) {
      Clipboard.setData(ClipboardData(text: info.toBody()?.body ?? ''));
      Loading.toast('im_chat_success_copy'.tr);
    }
  }

  /// 转发
  void menuForwardMsg(IMMessage info) {
    // 打开会话选择器，转发单条消息
    _forwardOneByOne([info]);
  }

  /// 收藏
  void menuCollectionMsg(IMMessage info) {
    _collectionMsgList([info]);
  }

  /// 多选
  void menuMultiSelect(IMMessage info) {
    state.isSelectMode = true;
    state.selectedMsgList.add(info);
  }

  /// 引用
  void menuAddQuoteMsg(IMMessage info) {
    state.quoteMessage.value = info;
  }

  /// 点击选择消息
  void clickSelectMsgItem(IMMessage info) {
    if (state.selectedMsgList.contains(info)) {
      state.selectedMsgList.removeWhere((e) => e.id == info.id);
    } else {
      state.selectedMsgList.add(info);
    }
  }

  bool isMessageSelected(IMMessage info) {
    return state.selectedMsgList.contains(info);
  }

  void quoteMsgClick(IMMessage info) {
    if (!state.isSelectMode) {
      clickMsgItem(info);
    }
  }
  /// 点击消息
  void clickMsgItem(IMMessage info) {
    messageTool.clickMsgItem(info);
  }


  /// 取消多选模式
  void cancelMultiSelect() {
    state.isSelectMode = false;
    state.selectedMsgList.clear();
  }

  void collectionMsgs() {
    if (state.selectedMsgList.isEmpty) {
      Loading.toast('im_chat_error_message_select_empty'.tr);
      return;
    }
    _collectionMsgList(state.selectedMsgList.toList());
    cancelMultiSelect();
  }

  /// 收藏消息
  Future<void> _collectionMsgList(List<IMMessage> msgList) async {
    if (msgList.isEmpty) {
      return;
    }
    var id = await MessageCommunicationService.to
        .collectionMessageSave(msgList.map((e) => e.id!).toList());
    if (id != null) {
      Loading.toast('im_chat_success_collection'.tr);
    }
  }

  /// 转发
  void forwardMsgs() {
    if (state.selectedMsgList.isEmpty) {
      Loading.toast('im_chat_error_message_select_empty'.tr);
      return;
    }
    final context = my_get.Get.context;
    if (context == null) {
      return;
    }

    final msgList = state.selectedMsgList.toList();
    // 选择分开转发还是合并转发
    O2UI.showBottomSheetWithCancel(context, [
      ListTile(
        onTap: () {
          Navigator.pop(context);
          _mergeMessageToMessageCollectionType(msgList);
          cancelMultiSelect();
        },
        title: Align(
          alignment: Alignment.center,
          child: Text('im_chat_msg_forward_merge'.tr,
              style: Theme.of(context).textTheme.bodyMedium),
        ),
      ),
      const Divider(height: 1),
      ListTile(
        onTap: () {
          Navigator.pop(context);
          _forwardOneByOne(msgList);
          cancelMultiSelect();
        },
        title: Align(
          alignment: Alignment.center,
          child: Text('im_chat_msg_forward_one_by_one'.tr,
              style: Theme.of(context).textTheme.bodyMedium),
        ),
      ),
    ]);
  }

  /// 合并转发
  _mergeMessageToMessageCollectionType(List<IMMessage> msgList) {
    List<IMMessage> descList = [];
    if (msgList.length > 4) {
      descList = msgList.sublist(0, 4);
    } else {
      descList.addAll(msgList);
    }
    String desc = '';
    for (var item in descList) {
      desc +=
          '${item.createPerson?.o2NameCut()}: ${item.toBody()?.conversationBodyString()}\n';
    }
    String title = 'im_chat_group_chat'.tr;
    if (conversationInfo?.type == O2.imConversationTypeSingle) {
      title = conversationInfo!.personList!.map((e) => e.o2NameCut()).join(',');
    }
    final body = _messageHistoryMsgBody(
        'im_chat_msg_forward_title'.trArgs([title]),
        desc,
        msgList.map((e) => e.id!).toList());
    var collectMsg = _createMsg(body);
    if (collectMsg != null) {
      _forwardOneByOne([collectMsg]);
    } else {
      OLogger.e('错误，没有创建消息');
    }
  }

  /// 转发多条
  Future<void> _forwardOneByOne(List<IMMessage> messages) async {
    // 先选择会话
    var result = await ConversationPickerPage.open();
    if (result != null && result is IMConversationInfo) {
      final conversationId = result.id;
      for (var message in messages) {
        var now = DateTime.now().ymdhms();
        var newMsg = IMMessage(
            id: _uuid.v1(),
            body: message.body,
            conversationId: conversationId,
            createPerson: O2ApiManager.instance.o2User?.distinguishedName,
            createTime: now,
            sendStatus: 1);
        if (conversationId == _conversationId) {
          _addMessageToUI(newMsg);
        }
        _sendMessageToServer(newMsg);
      }
    }
  }

  /// 删除引用消息
  void deleteQuoteMsg() {
    state.quoteMessage.value = null;
  }

  /// 输入框输入发送消息
  void onSendText() {
    final text = chatInputController.text.trim();
    OLogger.d("输入了 $text");
    if (text.isEmpty) {
      return;
    }
    var msg = _createMsg(_textMsgBody(text),
        quoteMessageId: state.quoteMessage.value?.id);
    if (msg != null) {
      if (state.quoteMessage.value != null) {
        msg.quoteMessage = state.quoteMessage.value;
      }
      _addMessageToUI(msg);
      _sendMessageToServer(msg);
    }
    // 清空输入框
    chatInputController.text = "";
    state.quoteMessage.value = null;
  }

  /// 发送表情
  void onSendEmoji(String emojiKey) {
    OLogger.d("发送表情 $emojiKey");
    if (emojiKey.isNotEmpty) {
      var msg = _createMsg(_emojiMsgBody(emojiKey));
      if (msg != null) {
        _addMessageToUI(msg);
        _sendMessageToServer(msg);
      }
    }
  }

  void onSendEmojiText(String emoji) {
    OLogger.d("添加表情 $emoji");
    final text = chatInputController.text;
    chatInputController.text = text + emoji;
    chatInputController.selection = TextSelection.fromPosition(
        TextPosition(offset: chatInputController.text.length));
    if (chatInputScrollController.hasClients) {
      chatInputScrollController.animateTo(
          chatInputScrollController.position.maxScrollExtent,
          duration: const Duration(milliseconds: 50),
          curve: Curves.easeOut);
    }
  }
  /// 添加换行 光标所在起始位置
  void addInputLineBreak() {
    final text = chatInputController.text;
    final position = chatInputController.selection.baseOffset;
    OLogger.d("添加换行符 position: $position text: ${text.length}");
    chatInputController.text = '${text.substring(0, position)}\n${text.substring(position)}';
    chatInputController.selection = TextSelection.fromPosition(TextPosition(offset: position));
  }

  /// 选择图片 或者 拍照
  Future<void> _pickImageByType(int type) async {
    XFile? file;
    if (type == 0) {
      // 相册
      file = await _imagePicker.pickImage(source: ImageSource.gallery);
    } else if (type == 1) {
      // 拍照
      if (!await O2Utils.cameraPermission()) {
        return;
      }
      file = await _imagePicker.pickImage(source: ImageSource.camera);
    }
    if (file != null) {
      _uploadFileAndSendMsg(file.path);
    }
  }

  ///
  /// 选择文件
  ///
  Future<void> _chooseFile() async {
    O2Utils.pickerFileOrImage((paths) {
      if (paths.isEmpty) {
        return;
      }
      String path = paths[0] ?? '';
      if (path.isEmpty) {
        return;
      }
      OLogger.d('选择了文件：$path');
      _uploadFileAndSendMsg(path);
    });
  }

  ///
  /// 声音文件上传 发送消息
  ///
  Future<void> uploadAndSendVoiceMsg(String voiceFilePath, int duration) async {
    IMMessageBody body = _voiceMsgBody(voiceFilePath, duration);
    var imMessage = _createMsg(body);
    if (imMessage != null) {
      OLogger.d("声音消息body1: ${imMessage.body}");
      _addMessageToUI(imMessage);
      File file = File(voiceFilePath);
      var fileRes = await MessageCommunicationService.to
          .uploadFileToIM(_conversationId!, body.type!, file);
      if (fileRes == null) {
        Loading.showError('im_chat_error_upload_fail'.tr);
        return;
      }
      body.fileId = fileRes.id;
      body.fileExtension = fileRes.fileExtension;
      body.fileName = fileRes.fileName;
      body.fileTempPath = null;
      imMessage.body = json.encode(body.toJson());
      OLogger.d("声音消息body2: ${imMessage.body}");
      _sendMessageToServer(imMessage);
    }
  }

  ///
  /// 上传文件 发送消息
  ///
  Future<void> _uploadFileAndSendMsg(String filePath) async {
    if (_conversationId == null) {
      OLogger.e("错误：没有会话ID 。。。。。。");
      return;
    }
    var fileExtension = filePath.fileNameExtension();
    if (fileExtension.isEmpty) {
      Loading.showError('im_chat_error_unknown_file'.tr);
      return;
    }
    OLogger.d("文件扩展名： $fileExtension");
    IMMessageBody body;
    switch (fileExtension) {
      case "jpg":
      case "jpeg":
      case "gif":
      case "png":
      case "bmp":
        body = _imageMsgBody(filePath);
        break;
      default:
        body = _fileMsgBody(filePath);
        break;
    }
    var imMessage = _createMsg(body);
    if (imMessage != null) {
      OLogger.d("消息body1: ${imMessage.body}");
      _addMessageToUI(imMessage);
      File file = File(filePath);
      var fileRes = await MessageCommunicationService.to
          .uploadFileToIM(_conversationId!, body.type!, file);
      if (fileRes == null) {
        Loading.showError('im_chat_error_upload_fail'.tr);
        return;
      }
      body.fileId = fileRes.id;
      body.fileExtension = fileRes.fileExtension;
      body.fileName = fileRes.fileName;
      body.fileTempPath = null;
      imMessage.body = json.encode(body.toJson());
      OLogger.d("消息body2: ${imMessage.body}");
      _sendMessageToServer(imMessage);
    }
  }

  void _addMessageToUI(IMMessage msg) {
    // 这里要加到最前面
    final oldList = state.msgList;
    var newList = <IMMessage>[msg];
    for (var i = 0; i < oldList.length; i++) {
      newList.add(oldList[i]);
    }
    state.msgList.clear();
    state.msgList.addAll(newList);
    // 滚动底部
    _delayScorllToBottom();
  }

  ///
  /// 发送消息到服务器
  ///
  Future<void> _sendMessageToServer(IMMessage msg) async {
    var id = await MessageCommunicationService.to.sendMessage(msg);
    if (id != null && id.id != null && id.id!.isNotEmpty) {
      _updateMsgData(id.id!, 0); // 发送正常
    } else {
      _updateMsgData(msg.id!, 2); // 发送失败
    }
  }

  ///
  /// 更新消息状态，把发送中改成
  ///
  void _updateMsgData(String msgId, int status) {
    int i = 0;
    IMMessage? msg;
    for (var element in state.msgList) {
      if (element.id == msgId) {
        msg = element;
        break;
      }
      i++;
    }
    if (msg != null) {
      msg.sendStatus = status;
      state.msgList[i] = msg;
    }
  }

  ///
  /// 文字消息
  ///
  IMMessageBody _textMsgBody(String text) {
    return IMMessageBody(type: IMMessageType.text.name, body: text);
  }

  ///
  /// 表情消息
  ///
  IMMessageBody _emojiMsgBody(String emoji) {
    return IMMessageBody(type: IMMessageType.emoji.name, body: emoji);
  }

  ///
  /// 表情消息
  ///
  IMMessageBody _locationMsgBody(LocationData locationData) {
    var body = IMMessageBody(
        type: IMMessageType.location.name,
        longitude: locationData.longitude,
        latitude: locationData.latitude,
        address: locationData.address,
        addressDetail: locationData.addressDetail);
    body.body = body.conversationBodyString();
    return body;
  }

  ///
  /// 文件消息
  ///
  IMMessageBody _voiceMsgBody(String fileTempPath, int duration) {
    var body = IMMessageBody(
        type: IMMessageType.audio.name,
        fileTempPath: fileTempPath,
        audioDuration: "$duration",
        fileExtension: fileTempPath.fileNameExtension(),
        fileName: fileTempPath.fileName());
    body.body = body.conversationBodyString();
    return body;
  }

  ///
  /// 文件消息
  ///
  IMMessageBody _fileMsgBody(String fileTempPath) {
    var body = IMMessageBody(
        type: IMMessageType.file.name,
        fileTempPath: fileTempPath,
        fileExtension: fileTempPath.fileNameExtension(),
        fileName: fileTempPath.fileName());
    body.body = body.conversationBodyString();
    return body;
  }

  ///
  /// 图片消息
  ///
  IMMessageBody _imageMsgBody(String fileTempPath) {
    var body = IMMessageBody(
        type: IMMessageType.image.name,
        fileTempPath: fileTempPath,
        fileExtension: fileTempPath.fileNameExtension(),
        fileName: fileTempPath.fileName());
    body.body = body.conversationBodyString();
    return body;
  }

  /// 聊天记录消息
  IMMessageBody _messageHistoryMsgBody(
      String title, String desc, List<String> messageIds) {
    var body = IMMessageBody(
        type: IMMessageType.messageHistory.name,
        messageHistoryTitle: title,
        messageHistoryDesc: desc,
        messageHistoryIds: messageIds);
    body.body = body.conversationBodyString();
    return body;
  }

  ///
  /// 创建一个新消息对象
  ///
  IMMessage? _createMsg(IMMessageBody body, {String? quoteMessageId}) {
    if (_conversationId != null) {
      var jsonBody = json.encode(body.toJson());
      var now = DateTime.now().ymdhms();
      return IMMessage(
          id: _uuid.v1(),
          body: jsonBody,
          conversationId: _conversationId,
          createPerson: O2ApiManager.instance.o2User?.distinguishedName,
          createTime: now,
          quoteMessageId: quoteMessageId,
          sendStatus: 1);
    }
    return null;
  }
}
